<script setup lang="ts">
import { onMounted, ref, h } from "vue";
import "@logicflow/core/dist/index.css";
import "@logicflow/extension/lib/style/index.css";
import LogicFlow from "@logicflow/core";
import { DndPanel } from "@logicflow/extension";
import { VxeFormPropTypes } from "vxe-pc-ui";
import { ReOrganizationTreeSelect } from "@/components/ReOrganizationTreeSelect";
import Start from "./customerNodes/Start";
import End from "./customerNodes/End";
import GeneralAuditing from "./customerNodes/GeneralAuditing";
import Judge from "./customerNodes/Judge";
const props = defineProps<{ widgetData: any[] | null | undefined }>();
const conditionOptions = ref([]);
LogicFlow.use(DndPanel);

interface AuditingDataModel extends Record<string, unknown> {
  auditorType: number;
  auditor?: number;
  auditorName?: string;
  auditingStepType: number;
}
interface JudgedDataModel extends Record<string, unknown> {
  field: string;
  fieldString: string;
  operate: string;
  operateString: string;
  value: string;
}

const lf = ref<LogicFlow>();
const dndPanel = ref<DndPanel>();
onMounted(() => {
  lf.value = new LogicFlow({
    container: document.getElementById("lf-container") as HTMLElement,
    grid: true,
    edgeType: `Judge`,
    snapline: true,
    keyboard: {
      enabled: true
    },
    plugins: [DndPanel]
  });
  lf.value.register(Start);
  lf.value.register(End);
  lf.value.register(GeneralAuditing);
  lf.value.register(Judge);
  lf.value.on("node:click,edge:click,blank:click", args => {
    if (showBusinessPanel.value) {
      showBusinessPanel.value = false;
    }
    const { data } = args;
    if (data) {
      selectedNodeId.value = data.id;
      if (data.type == "GeneralAuditing") {
        showAuditingNode.value = true;
        showBusinessPanel.value = true;
        const nodeProperties = lf.value
          .getNodeModelById(data.id)
          .getProperties() as AuditingDataModel;
        nodeProperties.auditingStepType;
        auditingData.value =
          Object.keys(nodeProperties).length == 0
            ? defaultAuditingData()
            : nodeProperties;
      } else if (data.type == "Judge") {
        showBusinessPanel.value = true;
        showAuditingNode.value = false;
        const edgeProperties = lf.value
          .getEdgeModelById(data.id)
          .getProperties() as JudgedDataModel;
        judgedData.value = edgeProperties;
        conditionOptions.value = [];
        props.widgetData.forEach(value => {
          if (["VxeInput", "VxeNumberInput"].indexOf(value.name) > -1) {
            conditionOptions.value.push({
              title: value.title,
              field: value.field
            });
          }
        });
      }
    }
  });
  dndPanel.value = lf.value.extension.dndPanel as DndPanel;
  dndPanel.value.setPatternItems([
    {
      type: "Start",
      text: "开始",
      label: "开始节点",
      icon: ""
    },
    {
      type: "GeneralAuditing",
      label: "审批节点",
      icon: "",
      className: "important-node"
    },
    {
      type: "End",
      text: "结束",
      label: "结束节点",
      icon: ""
    }
  ]);
  lf.value.render(null);
});
const getData = () => {
  return lf.value.getGraphData();
};
const defaultAuditingData = () => {
  return {
    auditor: null,
    auditorType: 0,
    auditorName: "",
    auditingStepType: 0
  };
};
const auditingData = ref<AuditingDataModel>(defaultAuditingData());
const defaultJudgedData = () => {
  return {
    field: "",
    operate: "=",
    value: ""
  } as JudgedDataModel;
};
const judgedData = ref<JudgedDataModel>(defaultJudgedData());
const auditingColumns: VxeFormPropTypes.Items = [
  {
    field: "auditorType",
    titleWidth: 100,
    title: "审批人类型",
    span: 24,
    itemRender: {
      name: "VxeSelect",
      options: [
        { label: "组织机构", value: 0 },
        { label: "用户", value: 1, disabled: true },
        { label: "角色", value: 2, disabled: true }
      ],
      events: {
        change: value => {
          auditingData.value.auditor = value.data.auditor;
        }
      }
    }
  },
  {
    field: "auditor",
    titleWidth: 100,
    title: "审批人",
    span: 24,
    slots: {
      default: ({ data }) => [
        h(ReOrganizationTreeSelect, {
          modelValue: auditingData.value.auditor,
          onNodeClick(nodeData: Recordable) {
            auditingData.value.auditor = nodeData.id;
            auditingData.value.auditorName = nodeData.name;
          }
        })
      ]
    }
  },
  {
    field: "auditingStepType",
    titleWidth: 100,
    title: "节点类型",
    span: 20,
    itemRender: {
      name: "VxeSwitch",
      props: {
        openLabel: "并行节点",
        closeLabel: "串行节点",
        openValue: 1,
        closeValue: 0
      },
      events: {
        change: value => {
          auditingData.value.auditingStepType = value.data.auditingStepType;
        }
      }
    }
  },
  {
    align: "center",
    span: 4,
    itemRender: {
      name: "VxeButtonGroup",
      options: [{ type: "submit", content: "保存", status: "primary" }],
      events: {
        click() {
          setProperties("node");
          showBusinessPanel.value = false;
        }
      }
    }
  }
];
const setProperties = (type: string) => {
  if (type == "node") {
    const node = lf.value.getNodeModelById(selectedNodeId.value);
    node.updateText(auditingData.value.auditorName);
    node.setProperties(auditingData.value);
  } else {
    const edge = lf.value.getEdgeModelById(selectedNodeId.value);
    const option = conditionOptions.value.find(
      x => x.field == judgedData.value.field
    );
    edge.updateText(
      `${option.title}${judgedData.value.operate}${judgedData.value.value}`
    );
    edge.setProperties(judgedData.value);
  }
  showBusinessPanel.value = false;
};
const showBusinessPanel = ref(false);
const showAuditingNode = ref(false);
const selectedNodeId = ref<string>("");
const renderDesign = data => {
  lf.value.render(data);
  showBusinessPanel.value = false;
};
defineExpose({ getData, renderDesign });
</script>

<template>
  <div>
    <div id="lf-container" style="width: 100%; height: 600px" ref="container" />
    <div class="business-div" v-if="showBusinessPanel">
      <el-card v-if="showAuditingNode">
        <vxe-form :data="auditingData" :items="auditingColumns"></vxe-form>
      </el-card>
      <el-card style="height: 100px" v-else>
        <el-row :span="24">
          <el-col :span="6">
            <vxe-select
              clearable
              filterable
              placement="top"
              :transfer="true"
              v-model="judgedData.field"
              placeholder="请选择"
            >
              <vxe-option
                v-for="c in conditionOptions"
                :key="c.field"
                :value="c.field"
                :label="c.title"
              ></vxe-option>
            </vxe-select>
          </el-col>
          <el-col :span="6">
            <vxe-select
              v-model="judgedData.operate"
              placeholder=""
              placement="top"
              :transfer="true"
              clearable
              filterable
            >
              <vxe-option value="==" label="等于"></vxe-option>
              <vxe-option value=">" label="大于"></vxe-option>
              <vxe-option value="<" label="小于"></vxe-option>
              <vxe-option value=">=" label="大于等于"></vxe-option>
              <vxe-option value="<=" label="小于等于"></vxe-option>
              <vxe-option value="!=" label="不等于"></vxe-option>
            </vxe-select>
          </el-col>
          <el-col :span="6">
            <vxe-input v-model="judgedData.value" placeholder=""></vxe-input>
          </el-col>
          <el-col :span="6">
            <vxe-button
              status="primary"
              @click="setProperties('edge')"
              content="保存"
            ></vxe-button>
          </el-col>
        </el-row>
      </el-card>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.business-div {
  position: absolute;
  bottom: 0px;
  width: 100%;
}
</style>
